package ar.com.unlp.fi.lrs.controller;

import java.io.IOException;
import java.util.List;

import javax.ws.rs.Consumes;
import javax.ws.rs.core.MediaType;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.context.annotation.Scope;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import ar.com.unlp.fi.lrs.domain.Statement;
import ar.com.unlp.fi.lrs.service.ActorService;
import ar.com.unlp.fi.lrs.service.ContextService;
import ar.com.unlp.fi.lrs.service.StatementService;
import ar.com.unlp.fi.lrs.service.VerbService;

import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper;

/**
 * https://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#statement
 * 
 * 
 * 
 * 
 */
@RestController
@Scope(BeanDefinition.SCOPE_PROTOTYPE)
@RequestMapping(value = "/statement/")
public class StatementController {

	final static Logger logger = Logger.getLogger(StatementService.class);

	@Autowired
	private StatementService ss;

	@Autowired
	private ActorService actorService; 

	@Autowired
	private VerbService verbService;

	@Autowired
	private ContextService contextService;
	
	private int cont = 0;

	/**
	 * Controller para persistir un statement, el mismo es enviado en formato
	 * json.
	 * 
	 * @param statement
	 */
	@RequestMapping(value = "create", method = RequestMethod.POST, headers = "Accept=application/json")
	@Consumes(MediaType.APPLICATION_JSON)
	public void create(@RequestBody String json) {


		logger.info("Statement controller");
		ObjectMapper mapper = new ObjectMapper();

		Statement statement = null;
		try {
			statement = mapper.readValue(json, Statement.class);
		}
		catch (IOException e) {
			logger.error("Error al parsear el json", e);
		}

		// Se recupera el actor
		statement.setActor(actorService.get(statement.getActor().getId()));

		// Se recupera el verbo
		statement.setVerb(verbService.get(statement.getVerb().getId()));

		ss.create(statement);

		
		// TODO: persisttir el string json, para que quede registro del mismo y
		// pueda ser visualizado desde un panel de control.

	}

	/**
	 * Se obtiene un statement especifico.
	 * 
	 * @param id
	 * @return
	 */
	@RequestMapping(value = "get/{idStatement}", method = RequestMethod.GET, headers = "Accept=application/json")
	public Statement get(@PathVariable("idStatement") long id) {

		// TODO: obetener el idAgent al autenticar el agente.
		long idAgent = 1L;

		return ss.get(id, idAgent);
	}

	/**
	 * Retorna al lista de statements en formato JSon.
	 * 
	 * @param idActor
	 * @return
	 */
	@RequestMapping(value = "listStatements/{idActor}/{idGroup}", method = RequestMethod.GET, headers = "Accept=application/json")
	public List<Statement> listStatement(@PathVariable("idActor") long idActor,
			@PathVariable("idGroup") long idGroup) {

		return ss.getAll(idActor, idGroup);
	}

	/**
	 *	Web service para agregar un statement en el contexto de otro statement.
	 * 
	 */	
	@RequestMapping(value = "addExtension", method = RequestMethod.POST, headers = "Accept=application/json")
	@Consumes(MediaType.APPLICATION_JSON)
	public void addExtension( 
			@RequestBody String json) {

		ObjectMapper mapper = new ObjectMapper();

		long idStatement=0;
		Statement statement = null;
		try {
			
			String id=json.substring(0,json.indexOf("&"));
			json=json.substring(json.indexOf("&")+1);
			
			idStatement=Long.parseLong(id);
			statement = mapper.readValue(json, Statement.class);
		} catch (JsonParseException e) {
			e.printStackTrace();
		} catch (JsonMappingException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}

		// Se recupera el actor
		statement.setActor(actorService.get(statement.getActor().getId()));

		// Se recupera el verbo
		statement.setVerb(verbService.get(statement.getVerb().getId()));

		ss.create(idStatement, statement);

	}
	
	/**
	 * Se recuperan todos los statements relacionados
	 * 
	 * @param idStatement
	 * @return
	 */
	@RequestMapping(value = "getExtensions/{idStatement}", method = RequestMethod.GET, headers = "Accept=application/json")
	public List<Statement> getExtensions(@PathVariable("idStatement") long idStatement){
		
		return contextService.getExtensions(idStatement);
	}

//	/**
//	 * Se agrega un attachmetn al statement. Este attachement pueder un
//	 * archivo(pdf, doc, etc), un linek (youtube, una pagina), etc.
//	 * 
//	 */
//	public void addAttachment() {
//		// NOTE: Dejar para lo ultimo
//		// TODO
//	}
//
//	/**
//	 * Se obtiene el atachment.
//	 */
//	@RequestMapping(value = "attachment/{idStatement}", method = RequestMethod.GET, headers = "Accept=application/json")
//	public void getAttchment(@PathParam("idStatement") long idStatement) {
//		// NOTE: Dejar para lo ultimo
//		// TODO: Ver el tema de la trasferencia de archivos
//	}

}
